/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - system/task
// Copyright( c) 2014.  All Rights Reserved
//
// File:		AEScheduler.cpp
// Author:		Gianluca Belardelli
// Date:		30/06/2014
//
/////////////////////////////////////////////////////////////////////////
#include <AEEngine.h>

const AEFLOAT32 AEScheduler::sm_fDefaultClockFrequency = 1.0f / 120.0f;      // Set the timer to 120Hz

AEScheduler::AEScheduler( AETaskManager *lpTaskManager )
    : m_lpTaskManager( lpTaskManager )
    , m_fClockFrequency( sm_fDefaultClockFrequency )
    , m_hExecutionTimer( 0L )
    , m_bThreadingEnabled( 1 )
{
    //m_hExecutionTimer = Singletons::PlatformManager.Timers().Create( m_fClockFrequency );

	m_bBenchmarkingEnabled = 0;
		//Singletons::EnvironmentManager.Variables().GetAsBool( "AEScheduler::Benchmarking", False );
}

AEScheduler::~AEScheduler( void )
{
    //Singletons::PlatformManager.Timers().Destroy( m_hExecutionTimer );
}

/*
void AEScheduler::SetScene( const UScene* pScene )
{
    //
    // If we have a AETaskManager, then we can thread things.
    //
	m_bThreadingEnabled = ( m_lpTaskManager != NULL );
   
    //
    // Wait for any executing scenes to finish and clear out the list.
    //
	AESystemTaskI* lpScenesToWaitFor[ System::Types::MAX ];
    AEUINT32 uiScenesToWaitFor = 0;

    for ( SceneExecsIt it=m_SceneExecs.begin(); it != m_SceneExecs.end(); it++ )
    {
        AESystemSceneI* pSystemScene = it->second;

        AEASSERT( uiScenesToWaitFor < System::Types::MAX );
		lpScenesToWaitFor[ uiScenesToWaitFor++ ] = pSystemScene->GetSystemTask();
    }
    m_SceneExecs.clear();

    if ( uiScenesToWaitFor > 0 )
    {
		m_lpTaskManager->WaitForSystemTasks( lpScenesToWaitFor, uiScenesToWaitFor );
    }

    //
    // Copy over all the system scenes.
    //
    const UScene::SystemScenes& SystemScenes = pScene->GetSystemScenes();

    for ( UScene::SystemScenesConstIt it = SystemScenes.begin();
          it != SystemScenes.end(); it++ )
    {
        //
        // Make sure the system has a task.
        //
        if ( it->second->GetSystemTask() != NULL )
        {
            m_SceneExecs[ it->first ] = it->second;
        }
    }

    //
    // Re-create the timer as a scene load may have taken a long time.
    //
    Singletons::PlatformManager.Timers().Destroy( m_hExecutionTimer );
    m_hExecutionTimer = Singletons::PlatformManager.Timers().Create( m_fClockFrequency );
}
*/

void AEScheduler::Execute( void )
{
    //
    // Get the delta time; seconds since last Execute call.
    //
    AEFLOAT32 fDeltaTime;

	//
	//fDeltaTime = Singletons::PlatformManager.Timers().Wait( m_hExecutionTimer, !m_bBenchmarkingEnabled );

    //
	// Update instrumentation for this frame.
    // If we do this here, there's no thread sync to worry about since we're single-threaded here.
    
    //
	//Singletons::ServiceManager.Instrumentation().UpdatePeriodicData( fDeltaTime );

    //
    // Check if the execution is paused, and set delta time to 0 if so.
    //

/*    if ( Singletons::EnvironmentManager.Runtime().GetStatus() ==
         IEnvironment::IRuntime::Status::Paused )
    {
        fDeltaTime = 0.0f;
    }
*/

/*    if ( m_bThreadingEnabled )
    {
        //
        // Schedule the scenes that are ready for execution.
        //
        AESystemTaskI *lpScenesToExecute[ System::Types::MAX ];
        AEUINT32 uiScenesToExecute = 0;

        for ( SceneExecsIt it=m_SceneExecs.begin(); it != m_SceneExecs.end(); it++ )
        {
            AEASSERT( uiScenesToExecute < System::Types::MAX );
            AESystemSceneI* pSystemScene = it->second;
		    lpScenesToExecute[ uiScenesToExecute++ ] = pSystemScene->GetSystemTask();
        }

        m_lpTaskManager->IssueJobsForSystemTasks( lpScenesToExecute, uiScenesToExecute, fDeltaTime );

        //
        // Wait for the scenes that will be completing execution in this frame.
        //
#if 0
        AESystemTaskI *lpScenesToWaitFor[ System::Types::MAX ];
        AEUINT32 uiScenesToWaitFor = 0;

        for ( SceneExecsIt it=m_SceneExecs.begin(); it != m_SceneExecs.end(); it++ )
        {
            AEASSERT( uiScenesToWaitFor < System::Types::MAX );
            AESystemSceneI *pSystemScene = it->second;
		    lpScenesToWaitFor[ uiScenesToWaitFor++ ] = pSystemScene->GetSystemTask();
        }

        m_lpTaskManager->WaitForSystemTasks( lpScenesToWaitFor, uiScenesToWaitFor );*/
//#endif /* 0 */
/*        m_lpTaskManager->WaitForSystemTasks( lpScenesToExecute, uiScenesToExecute );
    }
    else
    {
        for ( SceneExecsIt it=m_SceneExecs.begin(); it != m_SceneExecs.end(); it++ )
        {
            AESystemSceneI* pSystemScene = it->second;
            pSystemScene->GetSystemTask()->Update( fDeltaTime );
        }
    }*/
}
